home *** CD-ROM | disk | FTP | other *** search
/ Stone Design / Stone Design.iso / Stone_Friends / Wave / WavesWorld / Source / IBPalettes / WW3DKit / WWSceneClock.new.m < prev    next >
Encoding:
Text File  |  1995-03-22  |  8.2 KB  |  361 lines

  1. // copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
  2. // see COPYRIGHT for reuse legalities
  3. //
  4.  
  5.  
  6. #import "WWSceneClock.h"
  7. #import "WW3DWell.h"  // for delegate routine
  8. #import "WWEveParser.h"  // for setTicksPerSecond
  9.  
  10. @implementation WWSceneClock
  11.  
  12. + initialize { return [WWSceneClock setVersion:2], self; }
  13.  
  14. - init
  15. {
  16.   [super init];
  17.  
  18.   currentTime = 0.0;
  19.   samplesPerSecond = 60.0;
  20.   increment = 1./samplesPerSecond;
  21.   skip = 10. * increment;
  22.   timedEntry = (DPSTimedEntry)0;
  23.   ratio = 1.;
  24.   isPaused = YES;
  25.   mark = 3.0;
  26.  
  27.   return self;
  28. }
  29.  
  30. - awake
  31. {
  32.   [super awake];
  33.   timedEntry = (DPSTimedEntry)0;
  34.   isPaused = YES;
  35.   return self;
  36. }
  37.  
  38. - (BOOL)isPaused { return isPaused; }
  39.  
  40. - removeTimedEntry
  41. {
  42.   if (timedEntry)
  43.   {  DPSRemoveTimedEntry(timedEntry);
  44.      timedEntry = (DPSTimedEntry)0;
  45.      isPaused = YES;
  46.   }
  47.   isPaused = YES;
  48.   return self;
  49. }
  50.  
  51. - free
  52. {
  53.    [self removeTimedEntry];
  54.    return [super free];
  55. }
  56.  
  57. - reset:sender
  58. {
  59.    [self removeTimedEntry];
  60.    currentTime = 0.0;
  61.    [delegate revertSceneClockInspector];
  62.    return self;
  63. }
  64.  
  65. - (float)mark { return mark; }
  66.  
  67. - setMark:(float)newMark 
  68. {  mark = newMark; 
  69.    [delegate revertSceneClockInspector];
  70.    return self; 
  71. }
  72.  
  73. - takeMark:sender
  74. {
  75.    [self setMark:[sender floatValue]];
  76.    return self;
  77. }
  78.  
  79. /////////////////////////////////////////////////////////////////////////
  80. ///////////////////////// increment /////////////////////////////////////
  81. /////////////////////////////////////////////////////////////////////////
  82. - (float)increment {  return increment; }
  83.  
  84. - increment:sender
  85. {
  86.    [self removeTimedEntry];
  87.    currentTime += increment;
  88.    [delegate revertSceneClockInspector];
  89.    return self;
  90. }
  91.  
  92. - setIncrement:(float)newIncrement
  93. {
  94.    if (newIncrement <= 0.0)
  95.    {  NXLogError("sceneClockIncrement must be > 0.\n");
  96.       return nil;
  97.    }
  98.    increment = newIncrement;
  99.    // need to tell the model's interp about the value of samplesPerSecond
  100.    // set the increment appropriately...
  101.    samplesPerSecond = 1.0/increment;
  102.    [scene setTicksPerSecond:samplesPerSecond];
  103.    [delegate revertSceneClockInspector];
  104.    return self;
  105. }
  106.  
  107. /////////////////////////////////////////////////////////////////////////
  108. ///////////////////////// skip /////////////////////////////////////
  109. /////////////////////////////////////////////////////////////////////////
  110. - (float)skip {  return skip; }
  111.  
  112. - skip:sender
  113. {
  114.    [self removeTimedEntry];
  115.    currentTime += skip;
  116.    return self;
  117. }
  118.  
  119. - setSkip:(float)newSkip
  120. {
  121.    if (newSkip <= 0.0)
  122.    {  NXLogError("sceneClockSkip must be > 0.\n");
  123.       return nil;
  124.    }
  125.    skip = newSkip;
  126.    // need to tell the model's interp about the value of samplesPerSecond
  127.    // set the skip appropriately...
  128.    [delegate revertSceneClockInspector];
  129.    return self;
  130. }
  131.  
  132. /////////////////////////////////////////////////////////////////////////
  133. ///////////////////////// current time //////////////////////////////////
  134. /////////////////////////////////////////////////////////////////////////
  135. - (float)timestamp { return currentTime; }
  136. - setCurrentTime:(float)newTime
  137. {
  138.    if (newTime < 0.0)
  139.    {  NXLogError("negative time is not valid in WavesWorld.\n");
  140.       return nil;
  141.    }
  142.    [self removeTimedEntry];
  143.    currentTime = newTime;
  144.    [delegate revertSceneClockInspector];
  145.    return self;
  146. }
  147.  
  148.  
  149. - decrement:sender
  150. {
  151.    [self removeTimedEntry];
  152.    currentTime -= increment;
  153.    if (currentTime < 0.0)
  154.    {  currentTime = 0.0;
  155.    }
  156.    [delegate revertSceneClockInspector];
  157.    return self;
  158. }
  159.  
  160. static void fastForwardFunc(DPSTimedEntry tag, double now, char *userdata)
  161. {
  162.    WWSceneClock  *self = (id)userdata;
  163.  
  164.    self->currentTime += self->skip;
  165.    if (self->currentTime > self->mark)
  166.    {  // I'm at the stop mark; so stop
  167.       [self->delegate pause:nil];
  168.    }
  169.    // should probably send a msg to a delegate to tell it that the scene info has changed...
  170.    [self->delegate revertSceneClockInspector];
  171.  
  172.    return ;
  173. }
  174.  
  175. - fastForward:sender
  176. {
  177.    [self removeTimedEntry];
  178.    timedEntry = DPSAddTimedEntry((double)(increment * ratio),
  179.                  (DPSTimedEntryProc)fastForwardFunc,
  180.                  self,
  181.                  NX_MODALRESPTHRESHOLD);
  182.    isPaused = NO;
  183.    return self;
  184. }
  185.  
  186. static void rewindFunc(DPSTimedEntry tag, double now, char *userdata)
  187. {
  188.    WWSceneClock  *self = (id)userdata;
  189.  
  190.    self->currentTime -= self->skip;
  191.    if (self->currentTime < 0.0)
  192.    {  self->currentTime = 0.0;
  193.       // I'm totally rewound, stop 
  194.       [self->delegate pause:nil];
  195.    }
  196.    // should probably send a msg to a delegate to tell it that the scene info has changed...
  197.    [self->delegate revertSceneClockInspector];
  198.  
  199.    return ;
  200. }
  201.  
  202. - rewind:sender
  203. {
  204.    [self removeTimedEntry];
  205.    timedEntry = DPSAddTimedEntry((double)(increment * ratio),
  206.                  (DPSTimedEntryProc)rewindFunc,
  207.                  self,
  208.                  NX_MODALRESPTHRESHOLD);
  209.    isPaused = NO;
  210.    return self;
  211. }
  212.  
  213. - pause:sender
  214. {
  215.    [self removeTimedEntry];
  216.    [delegate revertSceneClockInspector];
  217.    return self;
  218. }
  219.  
  220. static void playFunc(DPSTimedEntry tag, double now, char *userdata)
  221. {
  222.    WWSceneClock  *self = (id)userdata;
  223.  
  224.    if (!self->waiting)  // great! we can increment!
  225.    {  self->currentTime += self->increment;
  226.    }
  227.    else
  228.    {  if (
  229.  
  230.       }
  231.    if (self->currentTime > self->mark)
  232.    {  // I'm at the stop mark; so stop
  233.       [self->delegate pause:nil];
  234.    }
  235.    else
  236.    {  // restart stuff
  237.       [self installHighFrequencyCheck];  // back to initial mode
  238.    }
  239.  
  240.    // should probably send a msg to a delegate to tell it that the scene info has changed...
  241.    [self->delegate revertSceneClockInspector];
  242.  
  243.    return ;
  244. }
  245.  
  246. - installLowFrequencyCheck
  247. {
  248.    [self removeTimedEntry];
  249.    timedEntry = DPSAddTimedEntry((double)(lowFrequency * increment * ratio),
  250.                  (DPSTimedEntryProc)playFunc,
  251.                  self,
  252.                  NX_MODALRESPTHRESHOLD);
  253.    startTime = ; // get current wall time
  254.    dropDeadTime = startTime + (increment * ratio);
  255.    count = 0;
  256.    waiting = YES;
  257.    isPaused = NO;
  258.    return self;
  259. }
  260.  
  261. - installHighFrequencyCheck
  262. {
  263.    [self removeTimedEntry];
  264.    timedEntry = DPSAddTimedEntry((double)(highFrequency * increment * ratio),
  265.                  (DPSTimedEntryProc)playFunc,
  266.                  self,
  267.                  NX_MODALRESPTHRESHOLD);
  268.    count = 0;
  269.    waiting = YES;
  270.    isPaused = NO;
  271.    return self;
  272. }
  273.  
  274. - play:sender
  275. {
  276.    return [self installHighFrequencyCheck];
  277. }
  278.  
  279. /////////////////////////////////////////////////////////////////////////
  280. ///////////////////////// samples/sec //////////////////////////////////
  281. /////////////////////////////////////////////////////////////////////////
  282. - (float)samplesPerSecond { return samplesPerSecond; }
  283.  
  284. - setSamplesPerSecond:(float)newRate 
  285.    if (newRate < 0.0)
  286.    {  NXLogError("scene sample rate must be positive, not %d\n", newRate);
  287.       return nil;
  288.    }
  289.    [self removeTimedEntry];
  290.    samplesPerSecond = newRate; 
  291.    increment = 1.0/samplesPerSecond; 
  292.    skip = 10. * increment;
  293.    [scene setTicksPerSecond:samplesPerSecond];
  294.    [delegate revertSceneClockInspector];
  295.    return self; 
  296. }
  297.  
  298. - (float)ratio { return ratio; }
  299.  
  300. - setRatio:(float)newRatio 
  301.    if (newRatio < 0.0)
  302.    {  NXLogError("the ratio of real time to scene time must be positive, not %d\n", newRatio);
  303.       return nil;
  304.    }
  305.    [self removeTimedEntry];
  306.    ratio = newRatio; 
  307.    [delegate revertSceneClockInspector];
  308.    return self; 
  309. }
  310.  
  311. - setDelegate:newDelegate { delegate = newDelegate; return self; }
  312. - setScene:newScene { scene = newScene; return self; }
  313.  
  314. // NeXTSTEP archiving:
  315.  
  316. #define typeVectorVersion1 "fffff"
  317. #define typeValuesVersion1 ¤tTime, &increment, &skip, &samplesPerSecond, &ratio
  318.  
  319. #define typeVector "ffffff"
  320. #define typeValues ¤tTime, &increment, &skip, &samplesPerSecond, &ratio, &mark
  321.  
  322. - read:(NXTypedStream*)stream 
  323. {
  324.   int version;
  325.  
  326.  
  327.   [super read:stream];
  328.  
  329.   version = NXTypedStreamClassVersion(stream,"WWSceneClock");
  330.   if (version == 0) NXReadTypes(stream,"i",&version), version=1;
  331.   if (version == 1)
  332.   {  NXReadTypes(stream, typeVectorVersion1, typeValuesVersion1);
  333.      scene = NXReadObject(stream);
  334.      delegate = NXReadObject(stream);
  335.      mark = 3.0;
  336.   }
  337.   if (version == 2)
  338.   {  NXReadTypes(stream, typeVector, typeValues);
  339.      scene = NXReadObject(stream);
  340.      delegate = NXReadObject(stream);
  341.   }
  342.  
  343.   return self; 
  344. }
  345.  
  346. - write:(NXTypedStream*)stream 
  347. {
  348.   [super write:stream];
  349.  
  350.   NXWriteTypes(stream,typeVector, typeValues);
  351.   NXWriteObjectReference(stream, scene);
  352.   NXWriteObjectReference(stream, delegate);
  353.  
  354.   return self;
  355. }
  356.  
  357.  
  358. @end
  359.